@
@********************************************************************************************************
@                                                uC/OS-III
@                                          The Real-Time Kernel
@
@
@                           (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
@                    All rights reserved.  Protected by international copyright laws.
@
@                                           ARM Port
@
@ File      : OS_CPU_A.S
@ Version   : V3.01.2
@ By        : JJL
@             BAN
@             MJH
@
@ For       : ARM
@ Mode      : ARM
@ Toolchain : GNU
@********************************************************************************************************
@

@********************************************************************************************************
@                                          PUBLIC FUNCTIONS
@********************************************************************************************************

	.global OSStartHighRdy                                      @ Functions declared in this file
	.global OSCtxSw
	.global OSIntCtxSw


@********************************************************************************************************
@                                         START MULTITASKING
@                                      void OSStartHighRdy(void)
@
@ The pseudo code for this function is shown below:
@ OSStartHighRdy:
@   OSTaskSwHook();
@   SP = OSTCBHighRdyPtr->StkPtr;
@   OS_CTX_RESTORE
@   Return from Interrupt/Exception;
@********************************************************************************************************

OSStartHighRdy:
	bl OSTaskSwHook              	@ call user defined task switch hook

	@ SP = OSTCBHighRdyPtr->StkPtr
    ldr r0, =OSTCBHighRdyPtr     	@ get highest priority task TCB address
	ldr r0, [r0]
    ldr sp, [r0]                 	@ switch to the new stack

    ldmfd sp!, {r0}              	@ pop new task's cpsr
    msr spsr_cxsf, r0
    ldmfd sp!, {r0 - r12, lr, pc}^  @ pop new task's r0-r12,lr & pc


@*********************************************************************************************************
@                                PERFORM A CONTEXT SWITCH (From task level)
@                                           void OSCtxSw(void)
@
@ The pseudo code for this function is shown below:
@ OSCtxSw:
@   OS_CTX_SAVE
@   OSTCBCurPtr->StkPtr = SP;
@   OSTaskSwHook();
@   OSPrioCur   = OSPrioHighRdy;
@   OSTCBCurPtr = OSTCBHighRdyPtr;
@   SP          = OSTCBCurPtr->StkPtr;
@   OS_CTX_RESTORE
@   Return from Interrupt/Exception;
@*********************************************************************************************************

OSCtxSw:
	stmfd sp!, {lr}					@ push pc (lr should be pushed in place of PC)
	stmfd sp!, {r0 - r12, lr}		@ push lr & register file
	mrs r0, cpsr
	stmfd sp!, {r0}					@ push current cpsr

	@ OSTCBCurPtr->StkPtr = SP
	ldr r0, =OSTCBCurPtr	     	@ get current task TCB address
	ldr r0, [r0]
	str sp, [r0]                 	@ save to current sp

	bl OSTaskSwHook
	
	@ OSPrioCur = OSPrioHighRdy
	ldr r1, =OSPrioCur
	ldr r2, =OSPrioHighRdy
	ldrb r3, [r2]
	strb r3, [r1]
	
	@ OSTCBCurPtr = OSTCBHighRdyPtr
	ldr r0, =OSTCBCurPtr
	ldr r1, =OSTCBHighRdyPtr
	ldr r2, [r1]
	str r2, [r0]

	@ SP          = OSTCBCurPtr->StkPtr
	ldr r0, [r0]
    ldr sp, [r0]                 	@ switch to the new stack

    ldmfd sp!, {r0}              	@ pop new task's cpsr
    msr spsr_cxsf, r0
    ldmfd sp!, {r0 - r12, lr, pc}^  @ pop new task's r0-r12,lr & pc


@*********************************************************************************************************
@                                PERFORM A CONTEXT SWITCH (From an ISR)
@                                        void OSIntCtxSw(void)
@
@ The pseudo code for this function is shown below:
@ OSIntCtxSw:
@    OSTaskSwHook();
@    OSPrioCur   = OSPrioHighRdy;
@    OSTCBCurPtr = OSTCBHighRdyPtr;
@    SP          = OSTCBCurPtr->StkPtr;
@    OS_CTX_RESTORE
@    Return from Interrupt/Exception;
@*********************************************************************************************************

OSIntCtxSw:
	bl OSTaskSwHook
	
	@ OSPrioCur = OSPrioHighRdy
	ldr r1, =OSPrioCur
	ldr r2, =OSPrioHighRdy
	ldrb r3, [r2]
	strb r3, [r1]

	@ OSTCBCurPtr = OSTCBHighRdyPtr
	ldr r0, =OSTCBCurPtr
	ldr r1, =OSTCBHighRdyPtr
	ldr r2, [r1]
	str r2, [r0]

	@ SP          = OSTCBCurPtr->StkPtr
	ldr r0, [r0]
	ldr sp, [r0]                 	@ switch to the new stack

    ldmfd sp!, {r0}              	@ pop new task's cpsr
    msr spsr_cxsf, r0
    ldmfd sp!, {r0 - r12, lr, pc}^  @ pop new task's r0-r12,lr & pc


